#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2022/12/21 14:35
# @Author  : afraidbenq
# @File    : multi_consumer.py
# @Software: PyCharm
# @Github  : github/afraidbenq
# @Email   : 329189987@qq.com
# @Desc    :
"""
多台设备消费策略指令
"""
import os
import re
import time
import sys
import datetime
import win32gui
import win32con

import yaml

sys.path.append("C:\Sourcetree\AppiumProject")
from common import logger
from common import multi_appium_desired
from db.sys_redis import redis_client
from view.ths_view.ashare_view import AshareView


class MultiConsumer(object):
    def __init__(self, config_file, device_dict):
        # 连接redis
        redis_client.init_redis_connect()
        self.redis = redis_client
        self.message_queue = []
        self.current_key = None
        self.current_driver = None
        self.current_step = None
        # 启动driver
        self.driver_list = multi_appium_desired(config_file, device_dict)
        self.driver_dict = {}
        self.ready()

    def ready(self):
        """
        初始化设备
        初始化失败时，单独重试
        失败超2次，提醒今日需要手动操作
        :return
        """
        error_time = {}
        while True:
            for driver in self.driver_list:
                udid = driver.capabilities['desired']['udid']
                if udid not in error_time:
                    error_time[udid] = 0
                logger.info(udid)
                real = driver.capabilities['desired']['real']
                logger.info(real)
                logger.info(self.driver_dict)
                if udid not in self.driver_dict:
                    try:
                        s = AshareView(driver)
                        if real:
                            s.enter_ashare_buy()
                        else:
                            s.enter_simulated_buy()
                        self.driver_dict[udid] = {"driver": driver, "check": True, "s": s, "real": real}
                    except Exception as e:
                        s.getScreenShot("init")
                        logger.error(f"{udid} 设备初始化失败！")
                        logger.error(e)
                        s.query_elements()
                        error_time[udid] += 1
                        logger.info(error_time)
                        if error_time[udid] >= 3:
                            self.driver_dict[udid] = {"driver": driver, "check": False, "s": None, "real": real}
                            continue
                        driver.close_app()
                        driver.launch_app()
            if len(list(self.driver_dict.keys())) == len(self.driver_list):
                logger.info(self.driver_dict)
                break

    def take_last(self, elem):  # 指定最后时间戳排序
        return elem.split(':')[-1]

    def standby(self):
        if all(not d["check"] for d in self.driver_dict.values()):
            logger.error(f"没有可运行的设备！自动退出！")
            return
        while True:
            try:
                self.message_queue = self.redis.keys(pattern="send:*")
                # 按时间戳排序 key指定哪个值排序，reverse = True 降序， reverse = False 升序（默认）
                self.message_queue.sort(key=self.take_last, reverse=False)
                logger.info(self.message_queue)
                if len(self.message_queue) > 0:
                    self.current_key = self.message_queue[0]
                    self.current_driver = self.current_key.split(':')[1] if self.current_key.split(':')[
                                                                                1] != "127.0.0.1" else \
                        self.current_key.split(':')[1] + ":" + self.current_key.split(':')[2]
                    self.current_step = eval(self.redis[self.current_key])
                    logger.info(self.current_driver)
                    logger.info(self.current_step)
                    if int(self.current_key.split(':')[-1]) < int(time.time()) - 300:
                        logger.info("当前操作key<{}>已过期! 删除处理!".format(self.current_key))
                        logger.info("删除操作{}".format(self.current_step))
                        del self.redis[self.current_key]
                        continue
                    elif self.current_step["step"] == "buy":
                        logger.info(f"{self.current_driver}执行买入")
                        if not self.driver_dict[self.current_driver]["check"]:
                            continue
                        logger.info(self.current_step)
                        code = self.current_step["code"]
                        name = self.current_step["name"]
                        price = self.current_step["price"]
                        amount = self.current_step["amount"]
                        limit_price = self.current_step["limit_price"]
                        if limit_price:
                            self.driver_dict[self.current_driver]["s"].buy(code, amount=amount, bidding=True)
                        else:
                            self.driver_dict[self.current_driver]["s"].buy(code, price=price, amount=amount)

                    elif self.current_step["step"] == "sale":
                        logger.info(f"{self.current_driver}执行卖出")
                        if not self.driver_dict[self.current_driver]["check"]:
                            continue
                        logger.info(self.current_step)
                        code = self.current_step["code"]
                        name = self.current_step["name"]
                        price = self.current_step["price"]
                        amount = self.current_step["amount"]
                        limit_price = self.current_step["limit_price"]
                        if limit_price:
                            self.driver_dict[self.current_driver]["s"].sale(code, amount=amount, bidding=True)
                        else:
                            self.driver_dict[self.current_driver]["s"].sale(code, price=price, amount=amount)

                    elif self.current_step["step"] == "withdrawal":
                        logger.info(f"{self.current_driver}执行撤单")
                        if not self.driver_dict[self.current_driver]["check"]:
                            continue
                        logger.info(self.current_step)
                        code = self.current_step["code"]
                        name = self.current_step["name"]
                        yes = self.current_step["yes"]

                    elif self.current_step["step"] == "query":
                        logger.info(f"{self.current_driver}执行查询")
                        if not self.driver_dict[self.current_driver]["check"]:
                            back_key = self.current_key.replace("send", "back")
                            info = {'position': {}, 'total_cangwei': '仓位 --', 'totalasset': '200,000.00',
                                    'totallosewin': '0.00', 'dangri_yingkui': '-', 'dangri_yingkuibi': '-',
                                    'totalworth': '0.00', 'canuse': '200,000.00', 'canget': '0.00'}
                            value = f'{info}'
                            self.redis.set(back_key, value)
                            continue
                        real_bool = self.driver_dict[self.current_driver]["real"]
                        info = self.driver_dict[self.current_driver]["s"].query_position(real_bool)
                        back_key = self.current_key.replace("send", "back")
                        value = f'{info}'
                        self.redis.set(back_key, value)

                    elif self.current_step["step"] == "check":
                        logger.info(f"{self.current_driver}执行设备运行状态检查")
                        back_key = self.current_key.replace("send", "back")
                        if self.current_driver in self.driver_dict:
                            check_json = {"check": self.driver_dict[self.current_driver]["check"]}
                            value = f'{check_json}'
                        else:
                            check_json = {"check": False}
                            value = f'{check_json}'
                        self.redis.set(back_key, value)

                    elif self.current_step["step"] == "exit":
                        logger.info(f"{self.current_driver}执行退出")
                        if not self.driver_dict[self.current_driver]["check"]:
                            continue
                        self.driver_dict[self.current_driver]["s"].exit()
                        del self.driver_dict[self.current_driver]

                    elif self.current_step["step"] == "execute":
                        driver = self.driver_dict[self.current_driver]["driver"]
                        s = self.driver_dict[self.current_driver]["s"]
                        command = self.current_step["command"]
                        logger.info(f"{self.current_driver}执行输入的命令{command}")
                        exec(command)

                    else:
                        logger.info("操作<{}>未知!".format(self.current_step))
                        if not self.driver_dict[self.current_driver]["check"]:
                            continue
                        logger.info("执行standby...")
                    # 删除任务
                    logger.info("删除操作{}".format(self.current_step))
                    self.current_step = None
                    del self.redis[self.current_key]
                else:
                    time.sleep(1)
                    if not self.driver_dict:
                        break
            except Exception as e:
                logger.error(f"{self.current_driver}执行步骤：{self.current_step} 报错！")
                logger.error(e)
                if not self.driver_dict[self.current_driver]["check"]:
                    continue
                self.driver_dict[self.current_driver]["s"].getScreenShot(self.current_step["step"])
                # 先按物理返回键
                self.driver_dict[self.current_driver]["driver"].press_keycode(4)
                # 判断是否在首页
                if self.driver_dict[self.current_driver]["real"]:
                    self.driver_dict[self.current_driver]["s"].click_transaction_tab()
                    self.driver_dict[self.current_driver]["s"].click_buy_menu()
                else:
                    # self.driver_dict[self.current_driver]["s"].enter_simulated_buy()
                    self.driver_dict[self.current_driver]["s"].click_transaction_tab()
                    self.driver_dict[self.current_driver]["s"].click_buy_menu()
                logger.info("稍后重试操作{}".format(self.current_step))

        logger.info("设备服务关闭!")


if __name__ == '__main__':
    # 获取当前符号窗口句柄
    hwnd = win32gui.GetForegroundWindow()
    logger.info(hwnd)
    with open('C:\\Sourcetree\\GProject\\real_trading\\trading_day.yaml', 'r',
              encoding='utf-8') as file:
        trading = yaml.load(file, Loader=yaml.FullLoader)
    last_key = list(trading.keys())[0]
    logger.info(trading[last_key]['trading_date'])
    current_date = datetime.datetime.now().strftime('%Y-%m-%d')
    logger.info(current_date)
    if current_date in trading[last_key]['trading_date']:
        #             appium端口：[设备名称,设备udid,是否实盘标识]
        # device_dict = {"4723": ["夜神模拟器", "127.0.0.1:62001", False],
        #                "4725": ["夜神模拟器(1)", "127.0.0.1:62025", True]}
        device_dict = {}
        with open('C:\\Sourcetree\\GProject\\real_trading\\run_daily\\device_account_mapping.yaml', 'r',
                  encoding='utf-8') as file:
            data = yaml.load(file, Loader=yaml.FullLoader)
        equipment_list = list(data.keys())
        for device in equipment_list:
            if not data[device]['switch']:
                continue
            port = data[device]['port']
            name = data[device]['device']
            real = data[device]['real']
            device_dict[port] = [name, device, real]
        logger.info(device_dict)
        c = MultiConsumer('multi_desired_caps.yaml', device_dict)
        c.standby()
    else:
        logger.info(f"今天{current_date}不是交易日")
    # 关闭cmd窗口
    logger.info(hwnd)
    # 发送关闭窗口命令
    win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
